package com.gly091020.GLYCan.util;

import net.minecraft.core.NonNullList;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.Container;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

public interface CanContainer extends Container {
    @Override
    default int getContainerSize() {
        return 10;
    }

    @Override
    default boolean isEmpty() {
        return getItems().stream().allMatch(ItemStack::isEmpty);
    }

    @Override
    default ItemStack getItem(int i) {
        return getItems().get(i);
    }

    @Override
    default ItemStack removeItem(int i, int i1) {
        ItemStack stack = ContainerHelper.removeItem(getItems(), i, i1);
        this.setChanged();
        return stack;
    }

    @Override
    default ItemStack removeItemNoUpdate(int i) {
        ItemStack stack = ContainerHelper.takeItem(getItems(), i);
        this.setChanged();
        return stack;
    }

    @Override
    default void setItem(int i, ItemStack itemStack) {
        itemStack.limitSize(this.getMaxStackSize(itemStack));
        getItems().set(i, itemStack);
        this.setChanged();
    }

    @Override
    default boolean stillValid(Player player) {
        return true;
    }

    @Override
    default void clearContent() {
        getItems().clear();
        this.setChanged();
    }

    default void setItems(NonNullList<ItemStack> stacks){
        getItems().clear();
        if(stacks.size() > 10){
            throw new RuntimeException("太大了");
        }
        for(var i = 0;i < stacks.size(); i++){
            setItem(i, stacks.get(i));
        }
    }

    default boolean addItems(ItemStack stack){
        for (int i = 0; i < getItems().size(); i++) {
            if(getItems().get(i).isEmpty()){
                setItem(i, stack);
                return true;
            }
        }
        return false;
    }
    @NotNull
    NonNullList<ItemStack> getItems();

    default List<ItemStack> getMaxItems(){
        ArrayList<ItemStack> l = new ArrayList<>();
        var map = new HashMap<ItemStack, Integer>();
        for(ItemStack stack: getItems()){
            stack = stack.copy();
            if(stack.isEmpty()){continue;}
            var i = getItemIndexInMap(map, stack);
            if(i >= 0){
                var k = map.keySet().stream().toList().get(i);
                map.put(k, map.get(k) + 1);
            }else{
                map.put(stack, 1);
                l.add(stack);
            }
        }
        l.sort(Comparator.comparingInt(map::get));
        l.forEach(stack -> stack.setCount(map.getOrDefault(stack, 1)));
        return l.reversed();
    }

    default boolean isTomatoCan(){
        return getItems().stream().allMatch(stack ->
                stack.is(ItemTags.create(ResourceLocation.parse("c:crops/tomato"))));
    }

    private static int getItemIndexInMap(HashMap<ItemStack, Integer> map, ItemStack stack){
        int i = -1;
        for (int j = 0; j < map.size(); j++) {
            var stack1 = map.keySet().stream().toList().get(j);
            if(ItemStack.isSameItemSameComponents(stack, stack1)){
                i = j;
            }
        }
        return i;
    }

    @Override
    default boolean canPlaceItem(int slot, ItemStack stack) {
        return stack.has(DataComponents.FOOD) ||
                stack.has(DataComponents.POTION_CONTENTS) ||
                stack.has(DataComponents.SUSPICIOUS_STEW_EFFECTS);
    }

    @Override
    default int getMaxStackSize() {
        return 1;
    }
}
